package com.zhongke.cotrun.controller;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;

import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.zhongke.cotrun.common.payUtil.Do_http_request;
import com.zhongke.cotrun.common.payUtil.GlobalWX;
import com.zhongke.cotrun.common.payUtil.Sign;
import com.zhongke.cotrun.common.util.APIResponse;
import com.zhongke.cotrun.model.pojo.PayOrder;
import com.zhongke.cotrun.model.pojo.UserInfo;
import com.zhongke.cotrun.model.pojo.UserInforCompany;
import com.zhongke.cotrun.model.pojo.PayBankroll;
import com.zhongke.cotrun.model.pojo.PayCapitallog;
import com.zhongke.cotrun.model.pojo.PayMallInfo;
import com.zhongke.cotrun.model.pojo.PayMallType;
import com.zhongke.cotrun.model.resultpackage.CodeMsg;
import com.zhongke.cotrun.service.*;
import com.zhongke.cotrun.shiro.sys.shiro.ShiroUtils;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

 /**
 * @Description: 支付订单管理
 * @Author: songjing
 * @Date:   2020-03-20
 * @Version: V1.0
 */
@Api(tags = "支付订单管理")
@RestController
@RequestMapping("/payOrder")
@Validated
public class PayOrderController {
	private static final Logger logger = LoggerFactory.getLogger(PayOrderController.class);
	@Autowired
	private PayOrderService payOrderService;
	@Autowired
	private PayMallInfoService payMallInfoService;
	@Autowired
	private PayBankrollService payBankrollService;
	@Autowired
	private PayCapitallogService payCapitallogService;
	@Autowired
	private PayMallTypeService payMallTypeService;	
	@Autowired
	private WxSysDictService wxSysDictService;
	@Autowired
	private DictService dictService;
	@Autowired
	private UserInfoService userInfoService;
	/**
	 * 支付下单
	 * @param PayMallInfo
	 * @return
	 */
	@ApiOperation(value = "支付下单")
	@PostMapping(value = "/addOrder")
	public APIResponse addOrder(@RequestBody PayOrder payOrder) {		
		try {
			//验证提交表单
			if(payOrder == null || payOrder.getMallId() == null || StringUtil.isEmpty(payOrder.getPayType()) || payOrder.getMallNum() <= 0)
				return APIResponse.returnFail(CodeMsg.BIND_ERROR);
			
			//验证用户
			//UserInfo userInfo = userInfoService.selectUserInfoByid();
			if(ShiroUtils.getUserId1() == null)
				return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
			payOrder.setUserInfoId(ShiroUtils.getUserId1());
			
			//验证商品
			PayMallInfo payMallInfo = payMallInfoService.getById(payOrder.getMallId());
			if(payMallInfo == null)
				return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
			if("0".equals(payMallInfo.getIsEnable()))//下架的
				return APIResponse.returnFail(CodeMsg.PAY_MALL_ENABLE);
			if(payMallInfo.getStock() < payOrder.getMallNum())//库存小于本次下单的
				return APIResponse.returnFail(CodeMsg.PAY_MALL_STOCKFAIL);			
			
			payMallInfo.setStock(payMallInfo.getStock()-payOrder.getMallNum());//减库存
			payMallInfo.setVolume(payMallInfo.getVolume()+payOrder.getMallNum());//加销量
			
			//生成订单号
			String orderCode = payMallInfo.getTypeId()+payOrder.getUserInfoId()+String.valueOf(System.currentTimeMillis());
			payOrder.setOrderCode(orderCode);
			
			//实际支付金额=总额-优惠金额
			double totalPrice = payMallInfo.getPrice()*payOrder.getMallNum();
			if(totalPrice-payOrder.getCousePrice() < 0)
				return APIResponse.returnFail(CodeMsg.BIND_ERROR);
			payOrder.setActualPrice(totalPrice-payOrder.getCousePrice());
			if(payOrder.getActualPrice() < 0)
				payOrder.setActualPrice(0.00);
			
			long sTime = System.currentTimeMillis();//下单时间
			long dTime = sTime + 30 * 60 * 1000;//订单失效时间
			payOrder.setCreateDate(new Date(sTime));
			payOrder.setCreateBy(payOrder.getUserInfoId());//下单人
				
			Map<String, String> rmap = new HashMap<String, String>();
			rmap.put("orderCode", orderCode);
			
			if(payOrder.getActualPrice() > 0)
			{
				logger.info("=====pay  start======");
				SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
			    parameters.put("money", payOrder.getActualPrice()*100);
			    parameters.put("orderCode", payOrder.getOrderCode());
			    parameters.put("mallTitle", payMallInfo.getTitle());
			        
			    DateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
			    String sdate =  f.format(payOrder.getCreateDate());
			    String edate = f.format(new Date(dTime));
					
			    parameters.put("createDate", sdate);
			    parameters.put("endDate", edate);
			        
			    String sign = Sign.createSign("UTF-8", parameters,GlobalWX.SIGN_KEY);
			        
			    String url = "money="+(payOrder.getActualPrice()*100)+"&orderCode="+payOrder.getOrderCode()
								+"&mallTitle="+payMallInfo.getTitle()+"&createDate="+sdate+"&endDate="+edate
								+"&sign="+sign;
					
				Do_http_request neworder = new Do_http_request();	
				logger.info("=====pay  url======"+GlobalWX.IPAY_ORDER_URL+url);
				String returnStr = neworder.do_get(GlobalWX.IPAY_ORDER_URL,url);
				logger.info("===returnStr===="+returnStr);
				if(!"-1".equals(returnStr))
				 {
					rmap.put("payUrl",returnStr);
					payOrder.setPayUrl(returnStr);
				 }
				else
					return APIResponse.returnFail(CodeMsg.SERVER_ERROR);	
			}
			else
				payOrder.setState("1");
			
			if(payMallInfoService.updateById(payMallInfo)) //商品修改成功
			{
				payOrderService.save(payOrder);//保存订单
				rmap.put("orderId", String.valueOf(payOrder.getId()));
				
				logger.info("---------保存订单完成----------"+payOrder.getOrderCode());
				PayBankroll payBankroll = new PayBankroll();
				payBankroll.setUserInfoId(payOrder.getUserInfoId());
				payBankroll.setOrderId(payOrder.getId());
				payBankroll.setOrderCode(payOrder.getOrderCode());
				payBankroll.setAmount(payOrder.getActualPrice());
				payBankroll.setCommission(0.00);
				payBankroll.setOldblance(0.00);
				payBankroll.setNewblance(0.00);
				payBankroll.setType("income");
				payBankroll.setState("0");
				payBankroll.setPayType(payOrder.getPayType());
				payBankroll.setAmType("3");
				payBankroll.setCreateDate(new Date());
				payBankroll.setCreateBy(payOrder.getCreateBy());
				payBankrollService.save(payBankroll);//保存资金明细（账单）
				logger.info("---------保存保存资金明细完成----------"+payOrder.getOrderCode());
				return APIResponse.returnSuccess(rmap);
			}
			else
				return APIResponse.returnFail(CodeMsg.SERVER_ERROR);	
			
		} catch (Exception e) {
			logger.error("---------支付出现异常-----------"+e);
			return APIResponse.returnFail(CodeMsg.SERVER_ERROR);
		}
	}
	/**
	 * 支付下单回调
	 * @param PayMallInfo
	 * @return
	 */
	
	@PostMapping(value = "/payNotify")
	public void payNotify(HttpServletRequest request, HttpServletResponse response){		
		
		logger.info("------Server Name: " + request.getServerName() ); //获得服务器的名字 
		logger.info("------Server Port: " + request.getServerPort()); //获得服务器的端口号 
		logger.info("------Remote Addr: " + request.getRemoteAddr()); //获得客户端的ip地址 
		logger.info("------Remote Host: " + request.getRemoteHost()); //获得客户端电脑的名字，若失败，则返回客户端电脑的ip地址 
		try{
			 String money =  request.getParameter("money");
			 String orderCode=request.getParameter("orderCode");
			 String endTime=request.getParameter("endTime");
			 String inSign=request.getParameter("sign");
			 
			//if(!request.getRemoteAddr().equals(GlobalWX.WX_INCOME_NOTIFY_IP))
			//{
			//	 logger.error("------[orderCode:"+orderCode+"]-------通讯IP错误----end--");
			// 	 response.getWriter().write("NULL");
			//}
			//else
			 if(StringUtil.isEmpty(money) || StringUtil.isEmpty(orderCode) || StringUtil.isEmpty(endTime) || StringUtil.isEmpty(inSign)
					 || "0".equals(money))
			 {
				 logger.error("------[orderCode:"+orderCode+"]-------参数校验失败----end--");
				 response.getWriter().write("FAIL");
			 }
			 else
			 {
				 double amount = Double.valueOf(String.valueOf(money))/100;
				 logger.error("------[orderCode:"+orderCode+"]-------amount："+amount+"-----");
				 SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();
				 parameters.put("money", money);
				 parameters.put("orderCode", orderCode);
				 parameters.put("endTime", endTime);
				 String inCheckSign = Sign.createSign("UTF-8", parameters,GlobalWX.SIGN_KEY);
				 if(!inCheckSign.equals(inSign)){
					 logger.error("------[orderCode:"+orderCode+"]-------通讯密钥校验错误----end--");
					 response.getWriter().write("FAIL");
				 }
				 else{
					 PayBankroll payBankroll = payBankrollService.selectDetailByOrderCode(orderCode);
					 if(payBankroll != null && payBankroll.getAmount() == amount)
					 {
						if(!"0".equals(payBankroll.getState()) || !"income".equals(payBankroll.getType()))
						{
							logger.error("------[orderCode:"+orderCode+"]-------订单状态非“待付款”或非'入金'----end--");
							response.getWriter().write("success"); 
						}
						else
						{
							payBankroll.setState("2");
							DateFormat f = new SimpleDateFormat("yyyyMMddHHmmss");
							payBankroll.setPayDate(f.parse(endTime));
							
							PayCapitallog payCapitallog = new PayCapitallog();
							payCapitallog.setUserInfoId(payBankroll.getUserInfoId());
							payCapitallog.setOrderCode(payBankroll.getOrderCode());
							
							if("1".equals(payBankroll.getAmType()))
							{
								//payBankroll.setCommission(0.00);
								//payBankroll.setOldblance(0.00);
								payCapitallog.setMoneyBefore(0.00);
								//payBankroll.setNewblance(0.00);
								payCapitallog.setMoneyAdd(payBankroll.getAmount());
								payCapitallog.setMoneyAfter(0.00);								
								payCapitallog.setType("0");
								payCapitallog.setIncomeRemarks(payBankroll);
							}
							else if("3".equals(payBankroll.getAmType()))
							{
								PayOrder payOrder = payOrderService.getById(payBankroll.getOrderId());
								payOrder.setState("1");
								payOrder.setPayDate(payBankroll.getPayDate());
								payOrder.setUpdateDate(new Date());							
								payOrderService.updateById(payOrder);
								
								payCapitallog.setMoneyBefore(0.00);
								payCapitallog.setMoneyAdd(-1*payBankroll.getAmount());
								payCapitallog.setMoneyAfter(0.00);								
								payCapitallog.setMallId(payOrder.getMallId());
								payCapitallog.setType("21");
								payCapitallog.setIncomeRemarks(payBankroll);
							}							
							payBankrollService.updateById(payBankroll);
							logger.info("--------[orderCode:"+orderCode+"]--------订单状态更新为2----");

							payCapitallog.setCreateDate(new Date());
							payCapitallogService.save(payCapitallog);
							logger.info("--------[orderCode:"+orderCode+"]--------保存资金日志明细----");
							
							response.getWriter().write("success");   
						}
			       }
			       else
			    	 response.getWriter().write("fail");   
			   }   
			}  
		}
		catch(Exception e)
		{
			logger.error("--------回调处理出现异常----"+e);
		}
	}
	/**
	  * 分页列表查询
	 * @param rqRoom
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	  @ApiOperation(value = "根据主体主键及类型查询订单列表")
	  @GetMapping(value= {"/selectAllByMain"},produces = "application/json;charset=utf-8")
	  public APIResponse selectAllByMain(String searchKey,String state,String appraiseState,
			  @NotNull(message = "主体主键不能为空") Long mainId,
			  @NotNull(message = "主体类型不能为空") String mallType,
	  		@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10")Integer pageSize) {
	  if(ShiroUtils.getUserId1() == null)
	    	  return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
	  PageInfo page = payOrderService.selectAllByMain(mainId,mallType,searchKey,state,appraiseState,pageNum,pageSize);
	  List list = page.getList();
	  if(list != null && list.size()>0)
	  {
		for(int i=0;i<list.size();i++)
		{
			PayOrder payOrder = (PayOrder)list.get(i);
			if(payOrder != null)
			{
				UserInfo userInfo = userInfoService.selectUserInfoByid(payOrder.getUserInfoId().intValue());
				if(userInfo != null)
				{
					payOrder.setUserInfoPhone(userInfo.getPhoneNumber());
					if("1".equals(userInfo.getType()))
						payOrder.setUserInfoName(userInfo.getRealName());
					if("2".equals(userInfo.getType()))
					{
						UserInforCompany userInforCompany = userInfoService.selectUserInfoCompanyById(userInfo.getUserId());
						if(userInforCompany != null)
							payOrder.setUserInfoName(userInforCompany.getCompanyName());
					}
				}
				payOrder.setStateLable(wxSysDictService.getDictLabel(payOrder.getState(), "orderState",payOrder.getState()));
				payOrder.setPayTypeLable(wxSysDictService.getDictLabel(payOrder.getPayType(), "orderPayType",payOrder.getPayType()));
				payOrder.setSceneTypeLable(wxSysDictService.getDictLabel(payOrder.getSceneType(), "orderSceneType",payOrder.getSceneType()));
				payOrder.setIsBlanceLable(wxSysDictService.getDictLabel(payOrder.getIsBlance(), "orderIsBlance",payOrder.getIsBlance()));
				payOrder.setAppraiseStateLable(wxSysDictService.getDictLabel(payOrder.getAppraiseState(), "orderAppraiseState",payOrder.getAppraiseState()));
				payOrder.setMainTable(null);
			}
		}
	  }
	  return APIResponse.returnSuccess(page);
	}
	/**
	  * 分页列表查询
	 * @param rqRoom
	 * @param pageNo
	 * @param pageSize
	 * @param req
	 * @return
	 */
	  @ApiOperation(value = "查看自己的订单分页列表")
	  @GetMapping(value= {"/selectAllByMine"},produces = "application/json;charset=utf-8")
	  public APIResponse selectAllByMine(String searchKey,String state,String appraiseState,
	  		@RequestParam(defaultValue = "1") Integer pageNum, @RequestParam(defaultValue = "10")Integer pageSize) {
      if(ShiroUtils.getUserId1() == null)
    	  return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
	  PageInfo page = payOrderService.selectAllByMine(ShiroUtils.getUserId1(),searchKey,state,appraiseState,pageNum,pageSize);
	  List list = page.getList();
	  if(list != null && list.size()>0)
	  {
		for(int i=0;i<list.size();i++)
		{
			PayOrder payOrder = (PayOrder)list.get(i);
			if(payOrder != null)
			{
				
				payOrder.setStateLable(wxSysDictService.getDictLabel(payOrder.getState(), "orderState",payOrder.getState()));
				payOrder.setPayTypeLable(wxSysDictService.getDictLabel(payOrder.getPayType(), "orderPayType",payOrder.getPayType()));
				payOrder.setSceneTypeLable(wxSysDictService.getDictLabel(payOrder.getSceneType(), "orderSceneType",payOrder.getSceneType()));
				payOrder.setIsBlanceLable(wxSysDictService.getDictLabel(payOrder.getIsBlance(), "orderIsBlance",payOrder.getIsBlance()));
				payOrder.setAppraiseStateLable(wxSysDictService.getDictLabel(payOrder.getAppraiseState(), "orderAppraiseState",payOrder.getAppraiseState()));
				
				List<Map> mList = payMallInfoService.selectMainDetailByMainId(payOrder.getMainId(),payOrder.getMainTable());
				if(mList != null && mList.size() > 0)
				{
					payOrder.setImgAddrs(String.valueOf(mList.get(0).get("img_addrs")));
					payOrder.setTitle(String.valueOf(mList.get(0).get("activities_topic")));
				}
				payOrder.setMainTable(null);
			}
		}
	  }
	  return APIResponse.returnSuccess(page);
	}
	
	/**
	  * 通过id查询
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "查看订单详情")
	@GetMapping(value = "/selectDetail")
	public APIResponse selectDetail(@NotNull(message = "订单主键不能为空") Long id) {
		if(ShiroUtils.getUserId1() == null)
	    	  return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
		
		PayOrder payOrder = payOrderService.getById(id);
		if(payOrder==null) {
			return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
		}else {
			PayMallInfo payMallInfo = payMallInfoService.getById(payOrder.getMallId());
			if(payMallInfo != null)
			{
				PayMallType payMallType = payMallTypeService.getById(payMallInfo.getTypeId());				
				if(payMallType != null)
				{
					List<Map> mList = payMallInfoService.selectMainDetailByMainId(payMallInfo.getMainId(),payMallType.getMainTable());
					List<Map> dList = payMallInfoService.selectDetailListByOrderCode(payOrder.getOrderCode(),payMallType.getDetailTable());
					Map rmap = new HashMap();
					
					payOrder.setStateLable(wxSysDictService.getDictLabel(payOrder.getState(), "orderState",payOrder.getState()));
					payOrder.setPayTypeLable(wxSysDictService.getDictLabel(payOrder.getPayType(), "orderPayType",payOrder.getPayType()));
					payOrder.setSceneTypeLable(wxSysDictService.getDictLabel(payOrder.getSceneType(), "orderSceneType",payOrder.getSceneType()));
					payOrder.setIsBlanceLable(wxSysDictService.getDictLabel(payOrder.getIsBlance(), "orderIsBlance",payOrder.getIsBlance()));
					payOrder.setAppraiseStateLable(wxSysDictService.getDictLabel(payOrder.getAppraiseState(), "orderAppraiseState",payOrder.getAppraiseState()));
					rmap.put("orderInfo", payOrder);
					
					if(mList != null && mList.size() > 0) {
						Map mallInfo = mList.get(0);
						if(mallInfo.get("activities_industry")!=null){
							mallInfo.put("activities_industry_name",dictService.selectValueInCodes(mallInfo.get("activities_industry").toString()));
						}
						if(mallInfo.get("activities_type")!=null){
							mallInfo.put("activities_type_name",dictService.getByCode(mallInfo.get("activities_type").toString()).getValue());
						}
						rmap.put("mallInfo", mallInfo);
					}else
						rmap.put("mallInfo", null);
					if(dList != null && dList.size() > 0)
						rmap.put("detailList", dList);
					else
						rmap.put("detailList", null);
					
					return APIResponse.returnSuccess(rmap);
				}
			}
			return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
		}
	}
	/**
	  * 通过id更新订单状态
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "取消订单")
	@GetMapping(value = "/cancelOrder")
	public APIResponse cancelOrder(@NotNull(message = "订单主键不能为空") Long id) {
		if(ShiroUtils.getUserId1() == null)
	    	  return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
		
		PayOrder payOrder = payOrderService.getById(id);
		if(payOrder==null || !payOrder.getUserInfoId().equals(ShiroUtils.getUserId1())) {
			return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
		}else {
			//订单状态( 0-待付款，1-已付款 2-已完成 3-已取消 4-已关闭）
			/**
			 * 取消订单
			 * 【
			 * 		待付款:取消订单、立即支  付
			 * 		待使用:申请售后
			 * 		待评价:申请售后、评价
			 * 		已关闭:无操作
			 * 		已取消:无操作
			 * 】
			 */
			if("0".equals(payOrder.getState()))
			{
				PayBankroll payBankroll = payBankrollService.selectDetailByOrderCode(payOrder.getOrderCode());
				if(payBankroll != null && "0".equals(payBankroll.getState()))
				{
					payBankroll.setDelFlag("1");
					payBankrollService.updateById(payBankroll);
				}
				
				PayMallInfo payMallInfo = payMallInfoService.getById(payOrder.getMallId());
				if(payMallInfo == null)
					return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
				payMallInfo.setStock(payMallInfo.getStock()+payOrder.getMallNum());//加库存
				payMallInfo.setVolume(payMallInfo.getVolume()-payOrder.getMallNum());//减销量
				payMallInfoService.updateById(payMallInfo);
				
				payOrder.setState("3");
				payOrderService.updateById(payOrder);
				
				return APIResponse.returnSuccess("取消成功");			
			}
			else
				return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
		}
	}
	/**
	  * 通过订单号获取支付链接
	 * @param orderCdoe
	 * @param userId
	 * @return
	 */
	@ApiOperation(value = "订单支付")
	@GetMapping(value = "/goPay")
	public APIResponse goPay(@NotNull(message = "订单号不能为空") String orderCode) {
		if(ShiroUtils.getUserId1() == null)
	    	  return APIResponse.returnFail(CodeMsg.ACCOUNT_ERROR);
		
		PayOrder payOrder = payOrderService.selectDetailByOrderCode(orderCode);
		if(payOrder==null || !payOrder.getUserInfoId().equals(ShiroUtils.getUserId1())) {
			return APIResponse.returnFail(CodeMsg.DATA_EMPTY);
		}else {
			if("0".equals(payOrder.getState()))
				return APIResponse.returnSuccess(payOrder.getPayUrl());
			else
				return APIResponse.returnSuccess();
		}
	}
}

